<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<!-- 最后要同步渲染 -->

<body>
    <div id="root"></div>
    <script>
        let root = document.querySelector("#root")
        let nextUnitOfWork = null
        let fiber = {
            "type": "div",
            "props": {
                "id": "div1",
                "children": [
                    {
                        "type": "div",
                        "props": {
                            "children": [
                                {
                                    "type": "div",
                                    "props": {
                                        // "innerHTML": "里面1",
                                        "children": [
                                            {
                                                "type": "div",
                                                "props": {
                                                    "innerHTML": "里面1"
                                                }
                                            }
                                        ]
                                    }
                                }
                            ]

                        }
                    },
                    {
                        "type": "h3",
                        "props": {
                            "innerHTML": "里面2"
                        }
                    }
                ]
            }
        }


        //  1.这是判断render还是commit阶段
        let wipRoot = null;
        function createDOM(fiber) {
            const dom =
                fiber.type == 'TEXT_ELEMENT'
                    ? document.createTextNode('')
                    : document.createElement(fiber.type);

            Object.keys(fiber.props)
                .filter((key) => key !== 'children')
                .forEach((key) => (dom[key] = fiber.props[key]));

            return dom;
        }

        /**
            2.搞一个wiproot出来。表示有没有渲染完
        */

        function render(element, container) {
            // Root Fiber
            wipRoot = {
                dom: container,
                props: {
                    children: [element],
                },
                children: null,
                parent: null,
                sibling: null
                // alternate: currentRoot,
            };
            // deletion = [];
            nextUnitOfWork = wipRoot;
        }
        // 


        /*
            3.render和commit的关键是把fiber.parent的fiber提取出来
            这里去掉渲染
        */

        function performUnitOfWork(fiber) {
            // console.log(fiber)
            if (!fiber.dom) {
                fiber.dom = createDOM(fiber)
            }

            const elements = fiber.props.children
            // 建立fiber之间的联系
            for (let i in elements) {
                const newFiber = {
                    type: elements[i].type,
                    props: elements[i].props,
                    parent: fiber,
                    dom: null,
                    children: null,
                    sibling: null
                }
                // 只有第0个叫child，别的都叫做sibling
                // 第二个if是兄弟节点
                if (i == 0) {
                    fiber.children = newFiber
                } else {
                    fiber.children.sibling = newFiber
                }
                // if (i == 0) { 
                //     fiber.children = newFiber 
                // } else { 
                //     fiber.sibling = newFiber 
                // }

                // console.log(newFiber, prevSibling)

            }
            //找儿子,深度一直跑。
            // console.log(fiber)
            if (fiber.children) {
                return fiber.children
            }
            // 找兄弟
            let nextFiber = fiber
            while (nextFiber) {
                if (nextFiber.sibling) {
                    return nextFiber.sibling
                }
                // 找爸爸
                nextFiber = nextFiber.parent
            }
        }
        /*
            4.事件循环中添加一个commit阶段。保证异步渲染，同步提交
        */
        function workLoop(deadline) {
            // console.log(deadline.timeRemaining())
            let shouldRun = true;
            // 不忙的时候进行渲染,一直空闲就能一直跑这个循环
            while (nextUnitOfWork && shouldRun) {
                nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
                shouldRun = deadline.timeRemaining() > 1;
            }
            // console.log("d", nextUnitOfWork)
            if (!nextUnitOfWork && wipRoot) {
                commitRoot(wipRoot)
            }
            // 重新请求
            requestIdleCallback(workLoop);

        }

        function commitRoot() {
            commitWork(wipRoot.children)
            wipRoot = null
        }
        /*
            5.从根节点开始渲染
        */
        function commitWork(fiber) {
            if (!fiber) {
                return
            }
            const domParent = fiber.parent.dom
            domParent.appendChild(fiber.dom)
            commitWork(fiber.children)
            commitWork(fiber.sibling)
        }

        render(fiber, root)
        requestIdleCallback(workLoop)

    </script>

    <script>

    </script>
</body>

</html>